#include "game.h"
#include "iostream.h"

Game::Game()
{
	ufo = new UFO();

	//Setup planet positions
	int displayWidth = Iw2DGetSurfaceWidth();
	int displayHeight = Iw2DGetSurfaceHeight();
	planets[0] = new Planet(displayWidth - PLANET_RADIUS, displayHeight / 4, "planet");
	planets[1] = new Planet(displayWidth - PLANET_RADIUS, displayHeight * 3 / 4, "planet");
	planets[2] = new Planet(displayWidth / 2, PLANET_RADIUS, "planet");
	planets[3] = new Planet(displayWidth / 2, displayHeight / 2, "planet");
	planets[4] = new Planet(displayWidth / 2, displayHeight - PLANET_RADIUS, "planet");
	planets[5] = new Planet(PLANET_RADIUS, displayHeight / 4, "planet");
	planets[6] = new Planet(PLANET_RADIUS, displayHeight * 3 / 4, "planet");

	middleBox = BoundingBox(planets[3]->position, planets[0]->position.x - planets[5]->position.x, planets[6]->position.y - planets[5]->position.y);
	topTriangle = BoundingTriangle(planets[2]->position, planets[5]->position, planets[0]->position);
	bottomTriangle = BoundingTriangle(planets[6]->position, planets[1]->position, planets[4]->position);

	//Create fuels
	fuels[0] = new Fuel();
	fuels[1] = new Fuel();
	fuels[2] = new Fuel();
	SpawnFuelInPlayArea(fuels[0]);
	SpawnFuelInPlayArea(fuels[1]);
	SpawnFuelInPlayArea(fuels[2]);

	//Comets
	comets[0] = new Comet();
	comets[1] = new Comet();

	//Power ups
	shield = new Shield();
	speed = new Speed();

	SetupImages();
}

Game::~Game()
{
	CleanupImages();

	delete ufo;

	for(i = 0; i < 7; i++)
	{
		delete planets[i];
	}

	for(i = 0; i < 3; i++)
	{
		delete fuels[i];
	}

	for(i = 0; i < 2; i++)
	{
		delete comets[i];
	}

	delete shield;
	delete speed;
}

void Game::Reset()
{
	fuelCount = 30;
	score = 0;

	SpawnFuelInPlayArea(fuels[0]);
	SpawnFuelInPlayArea(fuels[1]);
	SpawnFuelInPlayArea(fuels[2]);

	//Comets
	delete comets[0];
	delete comets[1];
	comets[0] = new Comet();
	comets[1] = new Comet();

	//Power ups
	delete shield;
	delete speed;
	shield = new Shield();
	speed = new Speed();
}

void Game::SetupImages()
{
	backgroundSprite = Iw2DCreateImageResource("background");
}

void Game::CleanupImages()
{
	if(backgroundSprite != NULL)
	{
		delete backgroundSprite;
		backgroundSprite = NULL;
	}

	for(i = 0; i < 7; i++)
	{
		planets[i]->CleanupImages();
	}

	for(i = 0; i < 3; i++)
	{
		fuels[i]->CleanupImages();
	}

	for(i = 0; i < 2; i++)
	{
		comets[i]->CleanupImages();
	}

	ufo->CleanupImages();

	shield->CleanupImages();
	speed->CleanupImages();
}

void Game::Render()
{
	Iw2DDrawImage(backgroundSprite, CIwSVec2(0, 0));

	for(i = 0; i < 7; i++)
	{
		planets[i]->Render();
	}

	for(i = 0; i < 3; i++)
	{
		fuels[i]->Render();
	}

	for(i = 0; i < 2; i++)
	{
		comets[i]->Render();
	}

	ufo->Render();

	shield->Render();
	speed->Render();
}

void Game::Update(int deltaTimeMs)
{
	CheckFuelCollision();
	CheckShieldCollision();
	CheckSpeedCollision();
	CheckCometCollision();

	UpdateInput(deltaTimeMs);

	for(i = 0; i < 7; i++)
	{
		planets[i]->Update(deltaTimeMs);
	}

	for(i = 0; i < 3; i++)
	{
		fuels[i]->Update(deltaTimeMs);
	}

	for(i = 0; i < 2; i++)
	{
		comets[i]->Update(deltaTimeMs);
	}

	ufo->Update(deltaTimeMs);

	shield->Update(deltaTimeMs);
	speed->Update(deltaTimeMs);

	if(shield->readyToSpawn)
	{
		SpawnShieldInPlayArea();
	}
	if(speed->readyToSpawn)
	{
		SpawnSpeedInPlayArea();
	}
}

void Game::UpdateInput(int deltaTimeMs)
{
	s3ePointerUpdate();
    s3eKeyboardUpdate();

	//Move ufo to clicked planet
	if(s3ePointerGetState(S3E_POINTER_BUTTON_SELECT) & S3E_POINTER_STATE_PRESSED)
    {
		Vector2 touchPosition = Vector2(s3ePointerGetX(), s3ePointerGetY());

		for(i = 0; i < 7; i++)
		{
			if(planets[i]->boundingBox.Intersects(touchPosition))
			{
				ufo->FlyTo(planets[i]->landPosition);
			}
		}
    }
}

void Game::CheckFuelCollision()
{
	for(i = 0; i < 3; i++)
	{
		if(fuels[i]->boundingBox.Intersects(ufo->boundingBox))
		{
			SpawnFuelInPlayArea(fuels[i]);
		}
	}
}

void Game::CheckShieldCollision()
{
	if(shield->boundingBox.Intersects(ufo->boundingBox))
	{
		ufo->ActivateShield();
		shield->UnSpawn();
	}
}

void Game::CheckSpeedCollision()
{
	if(speed->boundingBox.Intersects(ufo->boundingBox))
	{
		ufo->ActivateSpeed();
		speed->UnSpawn();
	}
}

void Game::CheckCometCollision()
{
	for(i = 0; i < 2; i++)
	{
		if(comets[i]->boundingBox.Intersects(ufo->boundingBox))
		{
			ufo->Crash();
		}
	}
}

void Game::SpawnFuelInPlayArea(Fuel* fuel)
{
	do
	{
		fuel->Spawn();
	}
	//If fuel does not spawn within the area accesible by the ufo, or it spawns on top of the ufo, respawn it
	while(ufo->boundingBox.Intersects(fuel->boundingBox) || (!middleBox.Intersects(fuel->position) && !topTriangle.Intersects(fuel->position) && !bottomTriangle.Intersects(fuel->position)));
}

void Game::SpawnShieldInPlayArea()
{
	do
	{
		shield->Spawn();
	}
	while(ufo->boundingBox.Intersects(shield->boundingBox) || (!middleBox.Intersects(shield->position) && !topTriangle.Intersects(shield->position) && !bottomTriangle.Intersects(shield->position)));
}

void Game::SpawnSpeedInPlayArea()
{
	do
	{
		speed->Spawn();
	}
	while(ufo->boundingBox.Intersects(speed->boundingBox) || (!middleBox.Intersects(speed->position) && !topTriangle.Intersects(speed->position) && !bottomTriangle.Intersects(speed->position)));
}